#include "mainscript.hpp"
#include <Shinygami/Applejack/world.hpp>
#include <Shinygami/texturelist.hpp>
#include <SFML/Graphics.hpp>
#include <iostream>

MyMainScript::MyMainScript(Shiny::Game& game, Shiny::Widgets::Ui& ui) : _game(game), _ui(ui)
{
    // Background
    std::cout << "Setting Window" << std::endl;
    game.SetWindowTitle("Mortal Louis de Pois");
    game.SetResolution(sf::Vector2f(1000.f, 800.f));
    game.SetFullscreen(true);

    std::cout << "Setting Background" << std::endl;

    Shiny::TextureList* texList      = ui.GetTextureList();
    if (texList)
    {
      const sf::Texture*        splashscreen = (*texList)["splashscreen"];

      if (splashscreen)
        _slapshscreen.SetTexture(*splashscreen);
    }

    std::cout << "Setting Menu" << std::endl;
    // Menu
    _mainMenu      = _ui.GetWidget<Shiny::Widgets::Ui>("mainMenu");
    _uiPicker      = _ui.GetWidget<Shiny::Widgets::Ui>("heroPicker");
    _pickerVisible = false;
    _numPlayers    = 2;

    if (!_mainMenu)
    {
	Shiny::ErrorManager::Get()->AddError("Invalid menu file (missing mainMenu)", Shiny::ErrorManager::StopGame);
	return ;
    }
    if (!_uiPicker)
    {
	Shiny::ErrorManager::Get()->AddError("Invalid menu file (missing heroPicker)", Shiny::ErrorManager::StopGame);
	return ;
    }
    //Shiny::Widgets::ControlEditor* controlEditor = new Shiny::Widgets::ControlEditor;

    //controlEditor->SetLeftToRight(true);
    //controlEditor->SetVerticalList(true);
    //controlEditor->GenerateControlList(controls);
    //controlEditor->SetSize(sf::Vector2f(400.f, 400.f));
    //_mainMenu->AddWidget(controlEditor);

    Shiny::Widgets::Container* buttonPicker = (*_mainMenu)["buttonPlay"];
    Shiny::Widgets::Container* buttonMenu   = (*_uiPicker)["buttonLeave"];
    Shiny::Widgets::Container* buttonPlay   = (*_uiPicker)["buttonPlay"];
    Shiny::Widgets::Container* buttonLeave  = (*_mainMenu)["buttonLeave"];

    if (buttonPicker) buttonPicker->Clicked.Connect(*this, &MyMainScript::PickerToggle);
    if (buttonMenu)   buttonMenu->Clicked.Connect(*this, &MyMainScript::PickerToggle);
    if (buttonPlay)  buttonPlay->Clicked.Connect(*this,  &MyMainScript::EventClicked);
    if (buttonLeave) buttonLeave->Clicked.Connect(*this, &MyMainScript::EventClicked);

    Shiny::Widgets::WidgetList* pickerQuantity = _uiPicker->GetWidget<Shiny::Widgets::WidgetList>("playerQuantity");
    Shiny::Widgets::WidgetList* pickerPlayer1  = _uiPicker->GetWidget<Shiny::Widgets::WidgetList>("pickerPlayer1");
    Shiny::Widgets::WidgetList* pickerPlayer2  = _uiPicker->GetWidget<Shiny::Widgets::WidgetList>("pickerPlayer2");
    Shiny::Widgets::WidgetList* pickerPlayer3  = _uiPicker->GetWidget<Shiny::Widgets::WidgetList>("pickerPlayer3");
    Shiny::Widgets::WidgetList* pickerPlayer4  = _uiPicker->GetWidget<Shiny::Widgets::WidgetList>("pickerPlayer4");

    pickerQuantity->SelectionChanged.Connect(*this, &MyMainScript::ChangePlayerQuantity);
    pickerPlayer1->SelectionChanged.Connect(*this, &MyMainScript::Hero1Picked);
    pickerPlayer2->SelectionChanged.Connect(*this, &MyMainScript::Hero2Picked);
    pickerPlayer3->SelectionChanged.Connect(*this, &MyMainScript::Hero3Picked);
    pickerPlayer4->SelectionChanged.Connect(*this, &MyMainScript::Hero4Picked);

    widgetPlayer1Pick = 0;
    widgetPlayer2Pick = 0;
    playerPick[0] = "louis";
    playerPick[1] = playerPick[0];
    playerPick[2] = playerPick[0];
    playerPick[3] = playerPick[0];
}

void MyMainScript::PickerToggle(Shiny::Widgets::Container* container, sf::Event)
{
    _pickerVisible = !_pickerVisible;
    _uiPicker->SetVisible(_pickerVisible);
    _mainMenu->SetVisible(!_pickerVisible);
}

void MyMainScript::Hero1Picked(Shiny::Widgets::Container* widget)
{
    widgetPlayer1Pick = widget;
    if (*widget == "pickMichael")
	playerPick[0] = "michael";
    else if (*widget == "pickLouis")
	playerPick[0] = "louis";
    else if (*widget == "pickAlex")
	playerPick[0] = "alex";
    else if (*widget == "pickYann")
	playerPick[0] = "yann";
}

void MyMainScript::Hero2Picked(Shiny::Widgets::Container* widget)
{
    widgetPlayer2Pick = widget;
    if (*widget == "pickMichael")
	playerPick[1] = "michael";
    else if (*widget == "pickLouis")
	playerPick[1] = "louis";
    else if (*widget == "pickAlex")
	playerPick[1] = "alex";
    else if (*widget == "pickYann")
	playerPick[1] = "yann";
}

void MyMainScript::Hero3Picked(Shiny::Widgets::Container* widget)
{
    widgetPlayer2Pick = widget;
    if (*widget == "pickMichael")
	playerPick[2] = "michael";
    else if (*widget == "pickLouis")
	playerPick[2] = "louis";
    else if (*widget == "pickAlex")
	playerPick[2] = "alex";
    else if (*widget == "pickYann")
	playerPick[2] = "yann";
}

void MyMainScript::Hero4Picked(Shiny::Widgets::Container* widget)
{
    widgetPlayer2Pick = widget;
    if (*widget == "pickMichael")
	playerPick[3] = "michael";
    else if (*widget == "pickLouis")
	playerPick[3] = "louis";
    else if (*widget == "pickAlex")
	playerPick[3] = "alex";
    else if (*widget == "pickYann")
	playerPick[3] = "yann";
}

void MyMainScript::ChangePlayerQuantity(Shiny::Widgets::Container *container)
{
    switch (container->GetName()[0])
    {
    case '2':
	_numPlayers = 2;
	(*_uiPicker)["pickerPlayer3"]->SetVisible(false);
	(*_uiPicker)["pickerPlayer4"]->SetVisible(false);
	break ;
    case '3':
	_numPlayers = 3;
	(*_uiPicker)["pickerPlayer3"]->SetVisible(true);
	(*_uiPicker)["pickerPlayer4"]->SetVisible(false);
	break ;
    case '4':
	_numPlayers = 4;
	(*_uiPicker)["pickerPlayer3"]->SetVisible(true);
	(*_uiPicker)["pickerPlayer4"]->SetVisible(true);
	break ;
    }
}

void MyMainScript::EventClicked(Shiny::Widgets::Container *container, sf::Event event)
{
    std::cout << "Callback clicked" << std::endl;
    if (*container == "buttonPlay")
    {
      Shiny::Game::LevelFactory factory = Shiny::Applejack::World::Factory::New;
      Shiny::Applejack::World*  world;
      Level1*                   script;

      std::cout << "BEGIN FACTORY" << std::endl;
      _game.LoadLevel(factory, "nivo");
      std::cout << "END FACTORY" << std::endl;
      world  = reinterpret_cast<Shiny::Applejack::World*>(_game.CurrentLevel());
      if (world)
      { 
	  // Load controls
	  DataTree* fileControls = DataTree::Factory::Yaml("./controls.yml");

	  if (fileControls)
	  {
	      Data      controls(fileControls);

	      _playersControl[0].LoadData(controls["player1"]);
	      _playersControl[1].LoadData(controls["player2"]);
	      _playersControl[2].LoadData(controls["player3"]);
	      _playersControl[3].LoadData(controls["player4"]);
	      delete fileControls;
	  }

	script = new Level1(*world, _numPlayers);
        world->SetModule(script);
	world->DisplayFps(true);
        script->EndLevel.Connect(*this, &MyMainScript::LevelEnded);
        script->SetScreenSize(_game.ScreenSize());
	for (char i = 0 ; i < _numPlayers ; ++i)
	  script->AddPlayer(i, playerPick[i], _playersControl[i]);
      }
    }
    else if (*container == "buttonLeave")
      _game.EndGame();
}

void MyMainScript::LevelEnded(bool)
{
    _game.EndLevel();
}

void MyMainScript::DrawMenuBackground(sf::RenderTarget& target)
{
    sf::Vector2f targetSize(target.GetWidth(), target.GetHeight());
    sf::Vector2f textSize(_slapshscreen.GetTexture()->GetWidth(), _slapshscreen.GetTexture()->GetHeight());

    _slapshscreen.SetScale(targetSize.x / textSize.x, targetSize.y / textSize.y);
    target.Draw( _slapshscreen);
}
